package com.dcits.business.server.linux;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.annotation.JSONField;
import com.dcits.business.server.MonitoringInfo;
import com.dcits.business.server.ViewServerInfo;
import com.dcits.business.server.linux.constant.CommandConstant;
import com.dcits.business.server.linux.parse.ParseInfo;
import com.dcits.tool.StringUtils;
import com.dcits.tool.ssh.SSHUtil;

import ch.ethz.ssh2.Connection;

public class LinuxServer extends ViewServerInfo {

	/**
	 * 
	 */
	
	public static final String SERVER_TYPE_NAME = "linux";
	
	private static final long serialVersionUID = 1L;
	private static final Map<String, Object> alertThreshold = new HashMap<String, Object>();
	public static final String LINUX_TYPE = "Linux";
	public static final String HPUX_TYPE = "HP-UX";
	public static final String SUNOS_TYPE = "SunOS";
	
	static {
		// TODO Auto-generated method stub
		alertThreshold.put(LinuxMonitoringInfo.CPU_FREE, 10);
		alertThreshold.put(LinuxMonitoringInfo.MEMORY_FREE, 10);
		alertThreshold.put(LinuxMonitoringInfo.DISK_USER, 90);
		alertThreshold.put(LinuxMonitoringInfo.IO_WAIT, 20);
		alertThreshold.put(LinuxMonitoringInfo.TCP_CLOSE_WAIT, 20000);
		alertThreshold.put(LinuxMonitoringInfo.TCP_TIME_WAIT, 20000);
	}
	
	/****************************************************/
	@JSONField(serialize=false)
	protected Connection conn;
	private String uname = LINUX_TYPE;
	private Integer cpuInfo = 0;
	private Long memInfo = 0L;
	private String[] mountDevices = new String[0];
	/**
	 * 可使用的命令
	 */
	@JSONField(serialize=false)
	private Map<String, String> commandMap;
	/****************************************************/
	
	public LinuxServer() {
		// TODO Auto-generated constructor stub
		super(new LinuxMonitoringInfo());
	}
	
	public LinuxServer(MonitoringInfo monitoringInfo) {
		// TODO Auto-generated constructor stub
		super(monitoringInfo);
	}
	
	@Override
	public String connect() {
		// TODO Auto-generated method stub
		try {
			this.conn = SSHUtil.getConnection(getHost(), getPort(), getUsername(), getPassword());
		} catch (Exception e) {
			// TODO: handle exception
			return "连接失败:" + e.getMessage();
		}
		if (this.conn != null) {
			//获取基本信息
			try {
				this.setUname(SSHUtil.execCommand(conn, CommandConstant.LINUX_COMMAND_MAP.get(CommandConstant.GET_UNAME), 1, 0, ""));
				
				switch (this.getUname()) {
				case LINUX_TYPE:
					this.setCommandMap(CommandConstant.LINUX_COMMAND_MAP);
					break;
				case HPUX_TYPE:
					this.setCommandMap(CommandConstant.HP_COMMAND_MAP);
					break;
				case SUNOS_TYPE:
					this.setCommandMap(CommandConstant.SUN_COMMAND_MAP);
					break;
				default:
					this.setCommandMap(CommandConstant.LINUX_COMMAND_MAP);
					break;
				}
				
				this.setCpuInfo(Integer.valueOf(SSHUtil.execCommand(conn, this.getCommandMap().get(CommandConstant.GET_CPU_INFO), 1, 0, "")));	
				this.setMemInfo(Long.valueOf(SSHUtil.execCommand(conn, this.getCommandMap().get(CommandConstant.GET_MEMORY_INFO), 1, 0, "")));
				this.setMountDevices(SSHUtil.execCommand(conn, this.getCommandMap().get(CommandConstant.GET_MOUNT_DEVICE_INFO), 999999, 0, "").split("\\n"));
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
					
		}		
		return "true";
	}

	@Override
	public boolean disconect() {
		// TODO Auto-generated method stub
		if (this.conn != null) {
			this.conn.close();
			
		}
		this.conn = null;
		return true;
	}

	@Override
	public void getMonitoringInfo() {
		// TODO Auto-generated method stub
		if (this.conn == null) {
			this.connectStatus = "无法连接主机";
			return;
		}
		monitoringInfo();
	}

	/**
	 * 使用jps命令检查当前java进程
	 * @return
	 * @throws Exception 
	 */
	public String checkJps(String javaHome) throws Exception {
		if (this.conn == null) {
			throw new Exception("请先连接到主机!");
		}
		return SSHUtil.execCommand(this.conn, javaHome + "/bin/jps|grep -vi jps", 100, 0, "");
	}
	
	/**
	 * 如果登录用户是root,则可以自行获取javaHome
	 * @return
	 */
	public String parseJavaHome() {
		String javaHome = "";
		try {
			javaHome = SSHUtil.execCommand(this.conn, "find / -name jps|sed -n '1p'", 1, 0, "");
			if (StringUtils.isNotEmpty(javaHome)) {
				javaHome = javaHome.substring(0, javaHome.lastIndexOf("/")).replace("/bin", "");
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return javaHome;
	}
	
	public void setMountDevices(String[] mountDevices) {
		this.mountDevices = mountDevices;
	}
	public String[] getMountDevices() {
		return mountDevices;
	}
	
	public Connection getConn() {
		return conn;
	}

	public void setConn(Connection conn) {
		this.conn = conn;
	}

	public String getUname() {
		return uname;
	}

	public void setUname(String uname) {
		this.uname = uname;
	}

	public Integer getCpuInfo() {
		return cpuInfo;
	}

	public void setCpuInfo(Integer cpuInfo) {
		this.cpuInfo = cpuInfo;
	}

	public Long getMemInfo() {
		return memInfo;
	}

	public void setMemInfo(Long memInfo) {
		this.memInfo = memInfo;
	}
	
	public void setCommandMap(Map<String, String> commandMap) {
		this.commandMap = commandMap;
	}
	
	public Map<String, String> getCommandMap() {
		return commandMap;
	}
	
	/**
	 * 获取动态信息
	 */
	public void monitoringInfo (){
		//实例化不同类型主机的信息解析类实例
		ParseInfo parseUtil = ParseInfo.getParseUtilInstance(this.uname);	
		
		LinuxMonitoringInfo monitoringInfo = (LinuxMonitoringInfo) this.info;

		try {
			//cpu  内存信息
			parseUtil.parseVmstatInfo(SSHUtil.execCommand(this.conn, this.commandMap.get(CommandConstant.VMSTAT), 5, 0, "")
					, monitoringInfo, this.uname, this.memInfo);				
			

			//处理tcp端口
			parseUtil.parseTcpInfo(SSHUtil.execCommand(this.conn
					, this.commandMap.get(CommandConstant.GET_TCP_PORT_COUNT), 1, 0, ""), monitoringInfo);
			
			//处理网络带宽
			parseUtil.parseNetworkInfo(SSHUtil.execCommand(this.conn
					, this.commandMap.get(CommandConstant.GET_NETWORK_INFO).replace("HOSTNAME", StringUtils.isEmpty(this.getRealHost()) ? this.getHost() : this.getRealHost()), 1, 0, "")
					, monitoringInfo);
			
			//处理磁盘空间使用信息 匹配 /和/username挂载的磁盘
			//while ((str = diskBrStat.readLine()).isEmpty()) {}	
			parseUtil.parseDiskInfo(SSHUtil.execCommand(this.conn
					, this.commandMap.get(CommandConstant.GET_DISK_INFO), 1, 0, ""), monitoringInfo);
			
			//处理设备IO读写
			parseUtil.parseDeviceIOInfo(SSHUtil.execCommand(this.conn, this.commandMap.get(CommandConstant.GET_IO_INFO)
					.replace("DEVICECOUNT", String.valueOf(this.mountDevices.length + 6)), 9999, 0, ""), monitoringInfo);
			
			monitoringInfo.setTime(new Date());	
			this.connectStatus = "true";
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			this.connectStatus = "获取信息发生错误:" + e.getMessage();
			this.disconect();			
		}
		
	}
	
}
